<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
  <meta name="keywords" content="hexo,个人博客,blog" />
  <meta name="description" content="赚钱，裸辞开店！！" />
  <meta http-equiv="x-dns-prefetch-control" content="on">
  <link rel="dns-prefetch" href="https://busuanzi.ibruce.info">
  <link rel="dns-prefetch" href="https://at.alicdn.com">
  
  <link rel="dns-prefetch" href="https://widget.daovoice.io">
  <link rel="dns-prefetch" href="https://widget-static-cdn.daovoice.io">
  <link rel="dns-prefetch" href="https://im.daovoice.io">
  
  
  <link rel="dns-prefetch" href="https://hm.baidu.com/">
  
  
  <link rel="stylesheet" type="text/css" href="/./style/main.css">
	<link rel="shortcut icon" href="/favicon.ico" title="Favicon">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.css">
	<title>spi学习</title>
  
  <script>var _hmt=_hmt||[];(function(){var hm=document.createElement("script");hm.src="https://hm.baidu.com/hm.js?awwssw1snsnsnn1ndndnndnd99j";var s=document.getElementsByTagName("script")[0];s.parentNode.insertBefore(hm,s);})();
  </script>
  
  
    <script>(function(i,s,o,g,r,a,m){i["DaoVoiceObject"]=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;a.charset="utf-8";m.parentNode.insertBefore(a,m)})(window,document,"script",('https:' == document.location.protocol ? 'https:' : 'http:') + "//widget.daovoice.io/widget/123456.js","daovoice");daovoice('init',{app_id: "123456"});daovoice('update');
  </script>
  
<meta name="generator" content="Hexo 6.3.0"></head>
<body>
  <canvas id="pattern-placeholder" height="230"></canvas>
<div class="navbar-header">
  <a class="blog-title" href="/">Kyist</a>
  <a class="face-img" href="/">
    <img src="/img/zz.png">
  </a>
</div>
<main>
  <div class="article-title">
    
  
  <h1 class="title">
    spi学习
  </h1>
  


    <ul class="article-info">
      <li>
        发布
        <time datetime="2023-03-15T14:18:46.000Z" itemprop="datePublished">2023-03-15</time>
      </li>
      <li>
        
    更新 <time datetime="2023-03-15T14:24:58.134Z" itemprop="dateUpdated">2023-03-15</time>

      </li>
      <li id="busuanzi_container_page_pv">
        阅读 <span id="busuanzi_value_page_pv"></span>
      </li>
    </ul>
  </div>
  <div class="container">
    <div class="article">
      <div class="content">
        
        <h5 id="SPI-Service-Provider-Interface-是JDK内置的一种服务提供发现机制，可以用来启用框架扩展和替换组件-主要用于框架中开发，例如Dubbo、Spring、等采用采用SPI机制，针对同一接口采用不同的实现提供给不同的用户，从而提高了框架的扩展性。"><a href="#SPI-Service-Provider-Interface-是JDK内置的一种服务提供发现机制，可以用来启用框架扩展和替换组件-主要用于框架中开发，例如Dubbo、Spring、等采用采用SPI机制，针对同一接口采用不同的实现提供给不同的用户，从而提高了框架的扩展性。" class="headerlink" title="SPI(Service Provider Interface)是JDK内置的一种服务提供发现机制，可以用来启用框架扩展和替换组件,主要用于框架中开发，例如Dubbo、Spring、等采用采用SPI机制，针对同一接口采用不同的实现提供给不同的用户，从而提高了框架的扩展性。"></a>SPI(Service Provider Interface)是JDK内置的一种服务提供发现机制，可以用来启用<strong>框架扩展</strong>和<strong>替换组件</strong>,主要用于框架中开发，例如Dubbo、Spring、等采用采用SPI机制，针对同一接口采用不同的实现提供给不同的用户，从而提高了框架的扩展性。</h5><p>Spring SPI沿用了Java SPI的设计思想，Spring采用的是spring.factories方式实现SPI机制，可以在不修改Spring源码的前提下，提供Spring框架的扩展性。</p>
<pre><code class="java">/**
 * demo
 *
 * @Author kyist
 * @Date 2023/3/15 00:01
 */
@Slf4j
public class Demo implements InitializingBean &#123;

    @Override
    public void afterPropertiesSet() throws Exception &#123;
        log.info(&quot;++++++++++++++++&#123;&#125;  and   &#123;&#125;++++++++++++++++++&quot;,&quot;kyist&quot;,&quot;Ccst&quot;);
    &#125;
&#125;


/**
 * 配置类
 * @Author kyist
 * @Date 2023/3/15 00:09
 */
@Configuration
public class Config &#123;

    @Bean
    @ConditionalOnMissingBean  //保证bean只有一个
    public Demo autoDemo()&#123;  
        return new Demo();
    &#125;

&#125;


/**
 * 类加载器
 * @Author kyist
 * @Date 2023/3/15 00:08
 */
@Import(Config.class)
public class SimpleLoader &#123;
&#125;




/**
 * 通过注解控制注入
 *
 * @Author kyist
 * @Date 2023/3/15 21:50
 */
public class EnableAutoSelector implements DeferredImportSelector, BeanClassLoaderAware &#123;

    private ClassLoader classLoader;
    @Override
    public void setBeanClassLoader(ClassLoader classLoader) &#123;
        this.classLoader = classLoader;
    &#125;


    @Override
    public String[] selectImports(AnnotationMetadata metadata) &#123;
        AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(EnableDemo.class.getName(), true));
        if(!attributes.getBoolean(&quot;enabled&quot;)) &#123;
            return new String[0];
        &#125;
        //加载META-INF/spring.factories 的配置
        List&lt;String&gt; strings = SpringFactoriesLoader.loadFactoryNames(EnableDemo.class, classLoader);
        return strings.toArray(new String[0]);
    &#125;
&#125;



/**
 * Demo控制注解
 *
 * @Author kyist
 * @Date 2023/3/15 21:51
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(EnableAutoSelector.class)  //注入选择器
public @interface EnableDemo &#123;

    boolean enabled() default true;
&#125;


</code></pre>
<p><img src="/2023/03/15/spi%E5%AD%A6%E4%B9%A0/image-20230315222445954.png" alt="image-20230315222445954"></p>

      </div>
        <div class="support-author">
          <p>感谢您的阅读。 🙏
          <a href="" target="_blank">关于转载请看这里</a>
            <!--<a class="btn-pay"  href="#pay-modal">¥ 打赏支持</a>-->
          </p>
        </div>
        <!--
            <div class="like ">
              <div class="like-button">
                <a id="like-note" href="">
                  <i class="icon-heart"></i>喜欢
                </a>
              </div>
              <span id="likes-count">256</span>
            </div>
        -->
        <div class="otherLink">
          <div class="previous">
          </div>
          <div class="next">
          </div>
        </div>
        <div class="comments" id="comments">
          

        </div>
      </div>
    </div>
   </div>
</main>
<div class="footer">
  <div class="info">
    <p>
    <a target="_blank" rel="noopener" href="https://hexo.io"> Hexo </a> 强力驱动 |
      <a target="_blank" rel="noopener" href="https://github.com/Youthink/hexo-themes-yearn"> Yearn </a>
      主题
    </p>
    <p>&copy;2013-2018 某某的博客 京ICP备xxxxxx号</p>
  </div>
</div>
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>

<script>//console
  var consoleConfig = ''.split(',');
  var canConsole = ;
  var consoleInfo = (function(consoleConfig) {
  if (!canConsole || !consoleConfig || consoleConfig.length < 1) {
    return;
  }
  var consoleColor = '#6190e8';
  var _console;
  var backgroundTextStyle = 'padding: 1px 5px;color: #fff;background: ' + consoleColor + ';'
  var textStyle = 'color: ' + consoleColor + ';';

  consoleConfig.map(o => {
    var num = (o.match(/%c/g) || []).length;
    if(/^http(s)?:\/\//.test(o)) {
      console.log('%c     ', 'background: url(' + o + ') no-repeat left center;font-size: 180px;');
      return;
    }
    if (num > 0) {
      var logArguments = [];
      for (var i = 0; i < num; i++) {
        if (i % 2 === 0) {
          logArguments.push(backgroundTextStyle);
        } else {
          logArguments.push(textStyle);
        }
      }
      (_console = console).log.apply(_console, ['%c' + o, textStyle].concat(logArguments));
      return;
    }
    console.log('%c' + o, textStyle);
  });
}(consoleConfig));</script><script type="text/javascript" src="/./js/main.js"></script>

  <script src="//at.alicdn.com/t/font_159214_mvtxvg9me9.js"></script>
</body>
</html>
